#ifndef VECTOR_H
#define VECTOR_H
#include <iostream>
#include <stdlib.h>
using namespace std;
template <class T>
class Vector
{
private:
    T *data;
    int theSize;
    int theMax;
    void Error(const char *cs) const
    {
        cout << cs << endl;
        exit(1);
    }

public:
    // explicit Vector(int n = 0) : theSize(0), theMax(n + SPARE_MAX)//
    explicit Vector(int n = 0) : theSize(n), theMax(n + SPARE_MAX) //这里原本的实现应该是有问题的
    {
        if (theMax > 0)
            data = new T[theMax];
    }
    Vector(const Vector &v) : data(nullptr), theMax(0)
    {
        operator=(v);
    }
    ~Vector(void)
    {
        delete[] data;
    }
    Vector &operator=(const Vector<T> &v);
    T &operator[](int id)
    {
        return (data[id]);
    }
    const T &operator[](int id) const
    {
        return (data[id]);
    }
    bool Empty(void) const
    {
        return (theSize == 0);
    }
    int Size(void) const
    {
        return (theSize);
    }
    int Max(void) const
    {
        return (theMax);
    }
    void Push_back(const T &item);
    void Pop_back(void);
    const T &Back(void) const;
    const T &Front(void) const;
    void Clear(void)
    {
        theSize = 0;
    }
    void Reserve(int newMax);
    void Resize(int newSize, const T &item = T());
    enum
    {
        SPARE_MAX = 16
    };

    typedef T *iterator;
    typedef const T *const_iterator;
    iterator begin()
    {
        return &data[0];
    }
    const_iterator begin() const
    {
        return &data[0];
    }
    iterator end()
    {
        return (&data[theSize]);
    }
    const_iterator end() const
    {
        return (&data[theSize]);
    }
    iterator Insert(iterator itr, const T &item);
    iterator Erase(iterator itr);
    int Count(const T &item) const
    {
        int res = 0;
        for (int i = 0; i < theSize; i++)
            if (item == data[i])
                res++;
        return res;
    }
    void print()
    {
        for (int i = 0; i < theSize; i++)
        {
            cout << data[i] << " ";
        }
        cout << endl;
    }
};

template <class T>
Vector<T> &Vector<T>::operator=(const Vector<T> &v)
{
    if (theMax != v.Max())
    {
        delete[] data;
        theMax = v.theMax;
        data = new T[theMax];
    }
    theSize = v.Size();
    for (int i = 0; i < theSize; i++)
        data[i] = v.data[i];
    return (*this);
}
template <class T>
void Vector<T>::Push_back(const T &item)
{
    if (theSize == theMax)
        Reserve(2 * theMax + 1);
    data[theSize++] = item;
}

template <class T>
typename Vector<T>::iterator
Vector<T>::Erase(iterator itr)
{
    if (theSize == 0)
        Error("Erase:an empty Vector!");
    if (itr < begin() || itr > end() - 1)
        Error("Erase: out of illegal!");
    for (iterator p = itr; p != end(); ++p)
        *p = *(p + 1);
    theSize--;
    return (itr);
}
template <class T>
typename Vector<T>::iterator
Vector<T>::Insert(iterator itr, const T &item)
{
    if (theSize == theMax)
        Reserve(2 * theMax + 1);
    if (itr < begin() || itr > end())
        Error("Insert:out of range");
    for (iterator p = end(); p != itr; --p)
        *p = *(p - 1);
    *itr = item;
    theSize++;
    return (itr);
}
template <class T>
void Vector<T>::Pop_back(void)
{
    if (theSize == 0)
        Error("Empty Vector!");
    theSize--;
}

template <class T>
const T &Vector<T>::Back(void) const
{
    if (theSize == 0)
        Error("Empty Vector!");
    return (data[theSize - 1]);
}
template <class T>
const T &Vector<T>::Front(void) const
{
    if (theSize == 0)
        Error("Empty Vector!");
    return (data[0]);
}
template <class T>
void Vector<T>::Reserve(int newMax)
{
    if (newMax < theSize)
        return;
    T *old = data;
    data = new T[newMax];
    for (int i = 0; i < theSize; i++)
        data[i] = old[i];
    theMax = newMax;
    delete[] old;
}
template <class T>
void Vector<T>::Resize(int newSize, const T &item)
{
    if (newSize > theMax)
        Reserve(newSize * 2 + 1);
    for (int i = theSize; i < newSize; i++)
        data[i] = item;
    theSize = newSize;
}

#endif
